/* your_device.h
 *
 * 放置字符设备驱动需要的公共定义（IOCTL CMD、私有数据结构、设备参数结构等）。
 * 供 platform_driver.c 和 char_driver.c 同时包含。
 */

#ifndef __YOUR_DEVICE_H__
#define __YOUR_DEVICE_H__

#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/device.h>

#define MAX_PLAT_DEVICES  8   /* 根据需要扩展 */

/* ===============================================================
 * IOCTL 命令定义
 * ===============================================================
 * 我们使用规范的 _IO、_IOR、_IOW、_IOWR 宏来定义 ioctl cmd。
 * “Y” 为魔数（任意选择一个不冲突的字符），设备号范围 0x00～0x1F：
 */
#define YOURDEV_IOC_MAGIC    'Y'

/* 无参数 ioctl */
#define YOURDEV_IOC_RESET       _IO(YOURDEV_IOC_MAGIC, 0x01)

/* 读取寄存器：用户传入一个 struct yourdev_reg { uint32_t offset; uint32_t value; }*/
struct yourdev_reg {
    uint32_t offset;
    uint32_t value;
};
#define YOURDEV_IOC_READ_REG    _IOWR(YOURDEV_IOC_MAGIC, 0x02, struct yourdev_reg)

/* 写寄存器：同上 */
#define YOURDEV_IOC_WRITE_REG   _IOW(YOURDEV_IOC_MAGIC, 0x03, struct yourdev_reg)

/* 获取设备状态：用户传入一个整数指针，内核将当前状态拷贝到它 */
#define YOURDEV_IOC_GET_STATUS  _IOR(YOURDEV_IOC_MAGIC, 0x04, int)

/* 设置设备参数：假设用一个简单的参数 struct yourdev_params { int param1; int param2; } */
struct yourdev_params {
    int param1;
    int param2;
};
#define YOURDEV_IOC_SET_PARAMS  _IOW(YOURDEV_IOC_MAGIC, 0x05, struct yourdev_params)

/* ===============================================================
 * 私有数据结构和平台初始化时需要的参数
 * ===============================================================
 */

/* 每个设备对应的私有数据（放在 char_driver.c 中实例化） */
struct yourdev_priv {
    void __iomem *base;        /* 映射后的寄存器基地址 */
    int irq;                   /* 中断号 */
    bool is_pcie;              /* 是否为 PCIe 设备 */
    struct pci_dev *pdev;      /* 如果是 PCIe 设备，保存 pci_dev 结构 */
    spinlock_t lock;           /* 自旋锁，用于保护对硬件寄存器/数据的访问 */
    struct cdev cdev;          /* 字符设备对象 */
    dev_t devt;                /* 分配到的设备号 */
    struct class *class;       /* 自动创建设备节点的 class */
    struct device *device;     /* 对应 /dev/yourdevX 的 device 结构 */
    uint32_t status;           /* 假设的设备状态，用于 ioctl GET_STATUS */
    struct yourdev_params params; /* 存储 ioctl SET_PARAMS 设置的参数 */
    /* ... 你可以根据需要再扩展更多私有成员 ... */
};

/* 平台驱动中会维护的设备条目信息 */
struct yourdev_plat_info {
    const char *name;      /* 设备名称，要与 char_driver.c 中的 of_device_id 或者 platform_device_id 对应 */
    bool is_pcie;          /* 是否为 PCIe 设备 */
    /* PCIe 设备特有字段 */
    uint16_t vendor_id;    /* PCIe 厂商 ID */
    uint16_t device_id;    /* PCIe 设备 ID */
    uint32_t offset;       /* 对于 PCIe 设备，从 BAR0 基地址加此偏移作为驱动使用的基地址 */
    /* 普通平台设备特有字段（非 PCIe） */
    resource_size_t phys_addr;  /* 物理地址 */
    resource_size_t size;       /* 物理地址长度 */
    int irq;                    /* 中断号 */
    /* 设备私有参数（可根据具体需求扩展） */
    int custom_param1;
    int custom_param2;
};

/* sysfs 属性节点对应的 store/show 函数会传入此结构体 */
struct yourdev_sysfs_attr {
    struct device *dev;
    struct yourdev_priv *priv;
};

#endif /* __YOUR_DEVICE_H__ */
